import json
import traceback

from constants import *
import logging
import requests as req

logger = logging.getLogger()
logging.basicConfig(level=logging.DEBUG,
                    filemode='a',
                    format='%(asctime)s [%(levelname)-5s] %(threadName)13s (%(module)s:%(funcName)s:%(lineno)d) - %(message)s'
                    )


class RequestURL:
    @staticmethod
    def post_url_data(json_data, retry_time=0):
        url = POST_URL
        if retry_time < 0:
            raise Exception("retry time should be larger than 0")
        retry_time = retry_time + 1
        while retry_time:
            try:
                rsp = req.post(url, json=json_data, timeout=2, headers=HEADERS)
                logger.info("send url: [{url}] data: [{data}]".format(url=url, data=json_data))
                if 200 <= rsp.status_code < 300:
                    retry_time = 0
                    return rsp.text, True
                else:
                    retry_time = retry_time - 1
                    logger.error("sending url [%s] , respone code:%s msg:%s", url, rsp.status_code, rsp.text)
                    if retry_time > 0:
                        time.sleep(10)
            except:
                retry_time = retry_time - 1
                logger.error(traceback.format_exc())
                logger.error("sending url [%s] failed retry %s" % (url, retry_time))
                if retry_time > 0:
                    time.sleep(10)
        return None, False

    @staticmethod
    def get_url_data(retry_time=0, projectInstanceId=None):
        if not projectInstanceId:
            logger.error("get projectInstanceId error!")
            return None, False
        url = GET_URL.format(projectInstanceId)
        while retry_time:
            try:
                logger.info("send url: [{url}]".format(url=url))
                rsp = req.get(url, headers=HEADERS)
                if 200 <= rsp.status_code < 300:
                    get_data = json.loads(rsp.text)
                    runState = get_data["data"]["runState"]
                    if runState == 2:
                        return runState, True
                    retry_time = retry_time - 1
                    logger.info("用例还在执行中...等在下次轮询...,此时runState为:{}".format(runState))
                    if retry_time > 0:
                        time.sleep(10)
                else:
                    retry_time = retry_time - 1
                    logger.error("sending url [%s] , respone code:%s msg:%s", url, rsp.status_code, rsp.text)
                    if retry_time > 0:
                        time.sleep(10)
            except:
                retry_time = retry_time - 1
                logger.error(traceback.format_exc())
                logger.error("sending url [%s] failed retry %s" % (url, retry_time))
                if retry_time > 0:
                    time.sleep(10)
        return None, False


class SynchronousGitea():
    def get_branch_name(self):
        GITLAB_CI_CHECK_INFO = os.getenv("GITLAB_CI_CHECK_INFO")
        logger.info("GITLAB_CI_CHECK_INFO:{}".format(GITLAB_CI_CHECK_INFO))
        if not GITLAB_CI_CHECK_INFO:
            return
        GITLAB_CI_CHECK_INFO = json.loads(GITLAB_CI_CHECK_INFO)
        return GITLAB_CI_CHECK_INFO.get("targetBranch", None)

    def req_url(self, branch_name):
        # 请求测试函数
        json_data = {
            "projectId": 113,
            "caseBranch": "master",
            "pageBranch": "master",
            "libBranch": branch_name,
            "taskCmd": "-t loginZcm",
            "notify": {
                "mode": 0,
                "instNotifies": None,
                "notifyPercent": 101
            }
        }
        post_text, flag = RequestURL.post_url_data(json_data, retry_time=10)
        if not flag:
            logger.error("启动执行测试用例失败！")
            return False
        post_data = json.loads(post_text)
        projectInstanceId = post_data["data"]["projectInstanceId"]
        logger.info("projectInstanceId为：{}".format(projectInstanceId))
        runState, flag = RequestURL.get_url_data(retry_time=60, projectInstanceId=projectInstanceId)
        if not flag:
            logger.error("测试用例执行失败！")
            return False
        if runState == 2:
            return True
        else:
            return False

    def run(self):
        branch_name = self.get_branch_name()
        logger.info("branch_name:[{}]".format(branch_name))
        if not branch_name:
            raise Exception("获取Lib测试分支信息失败！branch_name: [{}]".format(branch_name))
        req_code = self.req_url(branch_name)
        # req_code = self.req_url("structure_test")
        if not req_code:
            raise Exception("测试不通过，无法合入master！")


if __name__ == '__main__':
    sh = SynchronousGitea()
    sh.run()
